﻿//
// Created by LiuYou on 2021/4/26.
//

#include <string>
#include <sys/socket.h>
#include <iostream>
#include <cygwin/in.h>
#include <netdb.h>
#include <sys/unistd.h>
#include <cstring>

int main() {
    std::string serverIp("127.0.0.1");
    std::string serverPort("5001");

    auto clientSocketFD = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocketFD == -1) {
        std::cerr << "socket";
        return -1;
    }


    hostent* ptrHostEntry = gethostbyname(serverIp.c_str());
    if (ptrHostEntry == nullptr) {
        std::cerr << "获取主机(服务器)地址失败" << std::endl;
        close(clientSocketFD);
        return -1;
    }

    // TODO 注意: socket address internet
    // TODO 注意: sockaddr_in和sockaddr的区别
    // 此时创建的这个结构体对象不知道有什么用, 所以我也不知道怎么命名？
    // 但是我推测是想要连接的服务器的地址。
    sockaddr_in serverSockAddrIn{
            .sin_family=AF_INET,
            // 设置端口号, 使用网络字节顺序
            .sin_port=htons(std::stoi(serverPort))
    };
    memcpy(&serverSockAddrIn.sin_addr, ptrHostEntry->h_addr, ptrHostEntry->h_length);

    auto connectClientSocketFD = connect(clientSocketFD, (sockaddr*) &serverSockAddrIn, sizeof(serverSockAddrIn));
    if (connectClientSocketFD != 0) {
        std::cerr << "connect";
        close(clientSocketFD);
        return -1;
    }


    // 发送和接受
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++
    char buffer[1024];
    for (int i = 0; i < 4; ++i) {
        memset(buffer, 0, sizeof(buffer));
        std::strcpy(buffer, std::to_string(i).c_str());
        auto sendRet = send(clientSocketFD, buffer, std::strlen(buffer), 0);
        if (sendRet <= 0) {
            std::cerr << "send" << std::endl;
            break;
        }
        std::cout << "发送内容为: " << buffer << std::endl;

        sleep(2);

        // TODO 注意: 这里要注意: 如果Client写了recv函数, 那么Server一定一定一定一定一定要写send函数。
        //  否则: Client的recv函数接受不到信息, 就会一直在等待。

        // TODO 注意: 如果Client没写了recv, 那么Server写send函数可以, 不写也可以。
        //  Server写了send, 这Client如果没写recv函数, 还是可以继续执行Client的(不影响Client继续发送信息)。
        //  Server没写send, 也不会出错。此时就是Client发送, Server接受。然后Client和Server运行结束。
        std::memset(buffer, 0, sizeof(buffer));
        auto recvRet = recv(clientSocketFD, buffer, sizeof(buffer), 0);
        if (recvRet <= 0) {
            std::cout << "recvRet" << recvRet << std::endl;
            std::cerr << "recv";
            break;
        }
        std::cout << "Client接受的内容为: " << buffer << std::endl;
    }
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++

    close(clientSocketFD);

    return 0;
}